<?php
/**
 * 数据库助手
 * @param null $table 表名
 * @return $this|null|\Sys\Library\Connection
 */
function db($table = null)
{
    static $handle = null;
    if ($handle === null) {
        $config = config('database.mysql');
        $handle = new Sys\Library\Connection($config['host'], $config['port'], $config['username'], $config['password'], $config['database'], $config['prefix'], $config['charset']);
    }
    if($table === null) {
        return $handle;
    } else {
        return $handle->table($table);
    }
}

/**
 * 渲染模板
 * @param $name string 模板名称
 * @param array $params 参数
 * @return string
 */
function view($name, $params = array())
{
    global $twig;
    return $twig->render($name, $params);
}

/**
 * 浏览器友好的变量输出
 * @param mixed $var 变量
 * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串
 * @param string $label 标签 默认为空
 * @param boolean $strict 是否严谨 默认为true
 * @return void|string
 */
function dump($var, $echo = true, $label = null, $strict = true)
{
    $label = ($label === null) ? '' : rtrim($label) . ' ';
    if (!$strict) {
        if (ini_get('html_errors')) {
            $output = print_r($var, true);
            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
        } else {
            $output = $label . print_r($var, true);
        }
    } else {
        ob_start();
        var_dump($var);
        $output = ob_get_clean();
        if (!extension_loaded('xdebug')) {
            $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
        }
//        ob_end_clean();
    }
    if ($echo) {
        echo($output);
        return null;
    } else
        return $output;
}

/**
 * 记录和统计时间（微秒）和内存使用情况
 * 用法:
 * 先在某位置:G('start');
 * 最后的位置:G('start', 'end');//统计
 * @staticvar array $_info
 * @staticvar array $_mem
 * @param type $start
 * @param type $end
 * @return type
 */
function G($start, $end = '')
{//记录运行时间
    static $_info = array();
    static $_mem = array();
    if (!is_float($end) && !empty($end)) { //进行统计信息
        if (!isset($_info[$end])) $_info[$end] = microtime(true);
        if (!isset($_mem[$end])) {
            if (MEMORY_LIMIT_ON) $_mem[$end] = memory_get_usage();
        }
        //计算
        $time = number_format($_info[$end] - $_info[$start], 3);//秒
        $mem  = size2mb($_mem[$end] - $_mem[$start], 3);//bit
        return sprintf('总共耗时:%s秒,消耗内存:%s', $time, $mem);
    } else {
        $_info[$start] = $end ?: microtime(true);
        if (MEMORY_LIMIT_ON) $_mem[$start] = memory_get_usage();
    }
}

/**
 * 获取和设置配置参数 支持批量定义,最多支持三层结构
 * @param string|array $name 配置变量
 * @param mixed $value 配置值
 * @param mixed $default 默认值
 * @return mixed
 */
function config($name = null, $value = null, $default = null)
{
    static $_config = array();
    // 无参数时获取所有
    if (empty($name)) {
        return $_config;
    }
    // 优先执行设置获取或赋值
    if (is_string($name)) {
        if (!strpos($name, '.')) {
            $name = strtoupper($name);
            if (is_null($value))
                return isset($_config[$name]) ? $_config[$name] : $default;
            $_config[$name] = $value;
            return null;
        }
        // 二维数组设置和获取支持
        $name    = explode('.', $name);
        $name[0] = strtoupper($name[0]);
        if (is_null($value)) {
            if (count($name) == 2) {
                return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default;
            } else {
                return isset($_config[$name[0]][$name[1]][$name[2]]) ? $_config[$name[0]][$name[1]][$name[2]] : $default;
            }
        }
        if (count($name) == 2)
            $_config[$name[0]][$name[1]] = $value;
        else
            $_config[$name[0]][$name[1]][$name[2]] = $value;
        return null;
    }
    // 批量设置
    if (is_array($name)) {
        $_config = array_merge($_config, array_change_key_case($name, CASE_UPPER));
        return null;
    }
    return null; // 避免非法参数
}

if (!function_exists('is_https')) {
    /**
     * Is HTTPS?
     *
     * Determines if the application is accessed via an encrypted
     * (HTTPS) connection.
     *
     * @return    bool
     */
    function is_https()
    {
        if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
            return TRUE;
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https') {
            return TRUE;
        } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
            return TRUE;
        }

        return FALSE;
    }
}

if (!function_exists('is_really_writable')) {
    /**
     * Tests for file writability
     *
     * is_writable() returns TRUE on Windows servers when you really can't write to
     * the file, based on the read-only attribute. is_writable() is also unreliable
     * on Unix servers if safe_mode is on.
     *
     * @link    https://bugs.php.net/bug.php?id=54709
     * @param    string
     * @return    bool
     */
    function is_really_writable($file)
    {
        // If we're on a Unix server with safe_mode off we call is_writable
        if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR !ini_get('safe_mode'))) {
            return is_writable($file);
        }

        /* For Windows servers and safe_mode "on" installations we'll actually
         * write a file then read it. Bah...
         */
        if (is_dir($file)) {
            $file = rtrim($file, '/') . '/' . md5(mt_rand());
            if (($fp = @fopen($file, 'ab')) === FALSE) {
                return FALSE;
            }

            fclose($fp);
            @chmod($file, 0777);
            @unlink($file);
            return TRUE;
        } elseif (!is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE) {
            return FALSE;
        }

        fclose($fp);
        return TRUE;
    }
}

/**
 * 当机时发生
 */
function _shutdowHandle()
{
//    $ext = pathinfo($_SERVER['PHP_SELF'], PATHINFO_EXTENSION);
    if (error_get_last() == null) return;
    $info         = array();
    $info['发生时间'] = date('Y-m-d H:i:s');
    $info['最后错误'] = error_get_last();
    mylogger($info, '_shutdowHandle');
}

/**
 * 异常DEBUG
 * @param type $ex
 */
function _exceptionHandle($ex)
{
    $info         = array();
    $errno        = $ex->getCode();
    $info['发生时间'] = date('Y-m-d H:i:s');
    $info['错误号码'] = $errno;
    $info['异常信息'] = $ex->getMessage();
    $info['发生文件'] = $ex->getFile();
    $info['发生行号'] = $ex->getLine();
    mylogger($info, '_exceptionHandle');
}

/**
 * 错误函数
 */
function _errorHandle($errno, $errstr, $errfile, $errline)
{
    //admin为管理员的身份判定，true为管理员。
    //自定义的错误处理函数一定要有这４个输入变量$errno,$errstr,$errfile,$errline，否则无效。
    $info         = array();
    $info['发生时间'] = date('Y-m-d H:i:s');
    $info['错误号']  = $errno;
    $info['错误文件'] = $errfile;
    $info['错误行号'] = $errline;
    $info['错误信息'] = $errstr;
    switch ($errno) {
        case 8:
        case E_WARNING:
        case E_STRICT:
        case E_ERROR:
        case E_PARSE:
        case E_CORE_ERROR:
        case E_COMPILE_ERROR:
        case E_USER_ERROR:
        default:
            mylogger($info, '_errorHandle');
            break;
    }
}

/**
 * 写日志
 * @param $data
 * @param string $flag
 * @param bool $flush
 * @param string $title
 * @param string $filename
 */
function mylog($data, $flag = 'None', $flush = false, $title = '主站日志记录', $filename = 'debug')
{
    \Sys\Library\SgLogs::write($data, $flag, $flush, $filename, $title);
}

/**
 * 记录程序错误异常
 * @param $data
 * @param string $flag
 * @param string $method
 */
function mylogger($data, $flag = 'None', $method = 'a')
{
    $cacheFile = 'logger/logger-' . date("Ymd");
    mylog($data, $flag, $method, '日常日志记录', $cacheFile);
}

/**
 * 记录SQL
 * @param $data
 * @param string $flag
 * @param string $method
 */
function mylogsql($data, $flag = 'None', $method = 'a')
{
    $cacheFile = 'mysql/sql-' . date("Ymd");
    mylog($data, $flag, $method, '数据库日志记录', $cacheFile);
}

/**
 * 设置返回json
 * @param $status
 * @param null $msg
 * @param null $data
 * @return string
 */
function setJson($status, $msg = null, $data = null)
{
    $content = array(
        'status' => $status,
        'msg' => $msg
    );
    if ($msg === null) {
        $content['msg'] = 'ok';
    }
    if ($data !== null) {
        $content['data'] = $data;
    }
    return json_encode($content);
}

/**
 * 系统提示信息
 * 快捷操作:sys_message('xx', '信息', true)跳转
 * @param type $message
 * @param type $title
 */
function sys_show($message, $title = '提示信息', $href = '', $type = 'info', $auto_back = false)
{
    if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        exit(setJson(500, $message));
    }
    $type_msg   = '系统提示信息';
    $type_class = 'panel-primary';
    $a_class    = 'btn-success';
    if ($type == 'error') {
        $type_msg   = '错误提示信息';
        $type_class = 'panel-danger';
        $a_class    = 'btn-danger';
    }
    if (is_bool($href)) {
        $auto_back = $href;
    }
    $href = empty($href) ? 'javascript:window.history.back()' : $href;

    $auto_str = '';
    if ($auto_back) {
        $auto_str = "<meta http-equiv=\"refresh\" content=\"3;URL={$href}\" />";
    }
    $html = <<<__html
     <!doctype html>
<html>
    <head>
        <title>{$type_msg}</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        {$auto_str}
        <!-- 引入 Bootstrap -->
        <link href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <style type="text/css">
            .panel{
                margin:0 350px;
                margin-bottom:5px;
            }
        </style>
    </head>
    <body>
        <div class="panel {$type_class}">
            <div class="panel-heading">
                <h3 class="panel-title">{$title}</h3>
            </div>
            <div class="panel-body">
                {$message}
            </div>
            <div class="panel-footer text-center">
                <a href="{$href}" class="btn {$a_class} btn-block">确认</a>
            </div>
        </div>
    </body>
</html>
__html;
    exit($html);
}